from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad
import os

""" 
CBC 密码分组链接模式, 要使用初始化向量 IV 以增强安全性。
初始化加密,解密 对象, 减少重新创建对象开销

"""


class crypto_des_CBC:
    def __init__(self, key, iv):
        self.key = key
        self.iv = iv
        # self.cipher = DES.new(key, DES.MODE_CBC, iv)
        # self.uncipher = DES.new(key, DES.MODE_CBC, iv)

    def des_encrypt(self, data):
        cipher = DES.new(self.key, DES.MODE_CBC, self.iv)
        ciphertext = cipher.encrypt(pad(data.encode("utf-8"), DES.block_size))
        return ciphertext

    def des_decrypt(self, ciphertext):
        cipher = DES.new(self.key, DES.MODE_CBC, self.iv)
        plaintext = unpad(cipher.decrypt(ciphertext), DES.block_size)
        return plaintext.decode("utf-8")


def test():
    # 示例
    key = b"12345678"  # 固定密钥
    iv = os.urandom(8)  # 生成一个8字节的随机初始化向量
    crypt = crypto_des_CBC(key, iv)
    msg = ["hello world", "123456789", '{"reason" : "invalid password","status" : 403}']

    for data in msg:
        print("Original:", data)
        # 加密
        cipher_text = crypt.des_encrypt(data)
        print("Encrypted:", cipher_text.hex())
        # 解密
        plain_text = crypt.des_decrypt(cipher_text)
        print("Decrypted:", plain_text)


def test2():
    # 示例
    key = b"12345678"  # 固定密钥
    iv = os.urandom(8)  # 生成一个8字节的随机初始化向量
    crypt = crypto_des_CBC(key, iv)
    msg = ["hello world", "123456789", '{"reason" : "invalid password","status" : 403}']

    data = msg[2]
    cipher_text = crypt.des_encrypt(data)
    print("Encrypted:", cipher_text.hex())

    # 解密
    plain_text = crypt.des_decrypt(cipher_text)
    print("Decrypted:", plain_text)

    # 解密
    plain_text = crypt.des_decrypt(cipher_text)  # Error: DES CBC需要重置
    print("Decrypted:", plain_text)


if __name__ == "__main__":
    # test()
    test2()
